package com.topfinance.payment.service.impl;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Vector;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
//import org.springframework.beans.BeanUtils;

import com.topfinance.frame.dao.HibernateEntityDao;
import com.topfinance.frame.exception.AppException;
import com.topfinance.frame.util.BeanUtilsEx;
import com.topfinance.frame.util.StringUtil;
import com.topfinance.payment.ebo.TC2BisEleBscEbo;
import com.topfinance.payment.ebo.TC2BisEleExtEbo;
import com.topfinance.payment.ebo.TC2BisTpMsgEbo;
import com.topfinance.payment.service.ITC2BisEleBscMgr;

/**
 * 该类自动实现了dao的一般方法，如add, remove, update
 * 在service中出现的大部分情况下是在向后台提交数据前的处理(如校验)及获取后台数据后的处理等
 * @author
 *
 */

public class TC2BisEleBscMgrImpl extends HibernateEntityDao<TC2BisEleBscEbo> implements ITC2BisEleBscMgr {

	private static final Log log = LogFactory.getLog(TC2BisEleBscMgrImpl.class);
	
	//获得传输协议	
	public TC2BisEleBscEbo getTC2BisEleBsc(Integer oid) throws AppException{
		return (TC2BisEleBscEbo)get(oid);
	}

	public void deleteTC2BisEleBsc(Integer id) throws AppException{
		removeById(TC2BisEleBscEbo.class,id);
	}

	//获得传输协议列表
	public List<TC2BisEleBscEbo> getAllBisEleBsc() throws AppException{
		String hql = " from TC2BisEleBscEbo t " ;
		String where = "";
		List<Object> paramList = new ArrayList<Object>();
		if (isNotBlank(where)) {
			where = " where " + where;
		}
		hql = hql + where;
		return find(hql,paramList.toArray());
	}
	
	//根据msg获得要素集合,只从基本中获取
	public List<TC2BisEleBscEbo> getAllBisEle(String msg,String tpCode,String clsCode) throws AppException{
		String hql = " from TC2BisEleBscEbo t " ;
		String where = " t.msgCode = '" + msg + "'";
		List<TC2BisEleBscEbo> tpcls = null;
		String tpclsWhere = null;
		if(StringUtil.isNotNullStr(tpCode)&&StringUtil.isNotNullStr(clsCode)){
			tpclsWhere = " and t.eleBizs ='" + tpCode + "," + clsCode + "'";
			tpcls = find(hql+" where " + where+tpclsWhere);
		}else
			return find(hql + " where " + where);//没有类型和种类区分
		
		String tinyWhere = null;
		if(tpcls.size()>0){
			tinyWhere = " and (t.eleBizs is null or t.eleBizs ='" + tpCode + "," + clsCode + "')";
		}else{
			tinyWhere = " and (t.eleBizs is null or t.eleBizs = '" + tpCode + "')";
		}
		where += tinyWhere;
		List<Object> paramList = new ArrayList<Object>();
		if (isNotBlank(where)) {
			where = " where " + where;
		}
		hql = hql + where;
		return find(hql,paramList.toArray());
	}

	
	//根据条件获得要素集合
	public List<TC2BisEleBscEbo> getCfgedBisEle(String msg,String tpCode,String clsCode) throws AppException{
//		String hql = " from TC2BisEleBscEbo t " ;
//		String where = " t.msgCode = '" + msg + "'";
//		List<Object> paramList = new ArrayList<Object>();
//		if (isNotBlank(where)) {
//			where = " where " + where;
//		}
//		hql = hql + where;
//		List<TC2BisEleBscEbo> bscs = find(hql,paramList.toArray());
		List<TC2BisEleBscEbo> bscs = getAllBisEle(msg,tpCode,clsCode);
		Hashtable bscHash = new Hashtable();
		for(int i=0;i<bscs.size();i++){
			TC2BisEleBscEbo e = (TC2BisEleBscEbo)bscs.get(i);
			bscHash.put(e.getEleName(), e);
		}
		//在扩展表中找出需要替换的要素，只要是扩展要素中的ele_name,type,len,is_required,is_bis_defa_value
		List<TC2BisEleExtEbo> exts = getCfgedBisEle(msg,tpCode,null,"B");
		for (TC2BisEleExtEbo e : exts) {
			if(bscHash.containsKey(e.getSrcEleName())){
				TC2BisEleBscEbo b= (TC2BisEleBscEbo)bscHash.get(e.getSrcEleName());
				BeanUtilsEx.copyProperties(e, b);
			}
			//取消条件判断，主要原因在于基本要素也存在条件获取
			else
				System.out.println("[原始数据错B]" + msg + "," + tpCode + "," + clsCode+","+e.getSrcEleName());
		}
		
		//替换该类型中需要添加的要素和替换要素
		exts = getCfgedBisEle(msg,tpCode,null,"A");
		for (TC2BisEleExtEbo e : exts) {
			if(bscHash.containsKey(e.getEleName())){
				System.out.println("[原始数据错A]" + msg + "," + tpCode + "," + clsCode+ "," + e.getEleName());
				break;
			}
			TC2BisEleBscEbo b = new TC2BisEleBscEbo();
			BeanUtilsEx.copyProperties(e, b);
			b.setPath(e.getPrtNode()+"/"+e.getTagName());
			bscs.add(b);
			bscHash.put(b.getEleName(), b);
		}
		
		//在扩展表中找出需要替换的要素，只要是扩展要素中的ele_name,type,len,is_required,is_bis_defa_value
		exts = getCfgedBisEle(msg,tpCode,clsCode,"B");
		for (TC2BisEleExtEbo e : exts) {
			if(bscHash.containsKey(e.getSrcEleName())){
				TC2BisEleBscEbo b= (TC2BisEleBscEbo)bscHash.get(e.getSrcEleName());
				BeanUtilsEx.copyProperties(e,b);
			}else
				System.out.println("[原始数据错B]" + msg + "," + tpCode + "," + clsCode+","+e.getSrcEleName());
		}
		
		//覆盖或者替换该种类下要被替换的要素
		exts = getCfgedBisEle(msg,tpCode,clsCode,"M");
		for (TC2BisEleExtEbo e : exts) {
			if(bscHash.containsKey(e.getSrcEleName())){
				TC2BisEleBscEbo b= (TC2BisEleBscEbo)bscHash.get(e.getEleName());
				BeanUtilsEx.copyProperties(e, b);
			}else
				System.out.println("[原始数据错M]" + msg + "," + tpCode + "," + clsCode);
		}
		
		//添加该种类下要增加的要素和替换的要素
		exts = getCfgedBisEle(msg,tpCode,clsCode,"A");
		for (TC2BisEleExtEbo e : exts) {
			TC2BisEleBscEbo b = new TC2BisEleBscEbo();
			if(bscHash.containsKey(e.getEleName())){
				System.out.println("[原始数据错MA]" + msg + "," + tpCode + "," + clsCode);
				break;
			}
			BeanUtilsEx.copyProperties(e, b);
			b.setPath(e.getPrtNode()+"/"+e.getTagName());
			bscs.add(b);
			bscHash.put(b.getEleName(), b);
		}

		//添加该只有种类下的要素和替换的要素
		exts = getCfgedBisEle(msg,null,clsCode,"B");
		for (TC2BisEleExtEbo e : exts) {
			if(bscHash.containsKey(e.getSrcEleName())){
				TC2BisEleBscEbo b= (TC2BisEleBscEbo)bscHash.get(e.getSrcEleName());
				BeanUtilsEx.copyProperties(e, b);
			}
			//取消条件判断，主要原因在于基本要素也存在条件获取
			else
				System.out.println("[原始数据错B]" + msg + "," + tpCode + "," + clsCode+","+e.getSrcEleName());
		}
		
		return bscs;
	}
	
	//根据条件获得要素集合
	private List<TC2BisEleExtEbo> getCfgedBisEle(String msg,String tpCode,String clsCode,String appendType) throws AppException{
		//如果msg为空，返回空
		if(StringUtil.isNullStr(msg) )
			return new ArrayList();
		
		String hql = " from TC2BisEleExtEbo e " ;
		String where = " e.msgCode = '" + msg + "'";
		if(StringUtil.isNotNullStr(tpCode))
			where += " and e.tpCode = '" + tpCode + "'";
		if(StringUtil.isNotNullStr(clsCode))
			where += " and e.clsCode = '" + clsCode + "'";
		else
			where += " and e.clsCode is null";
		if(StringUtil.isNotNullStr(appendType))
			where += " and e.appendType = '" + appendType + "'";
		List<Object> paramList = new ArrayList<Object>();
		if (isNotBlank(where)) {
			where = " where " + where;
		}
		return find(hql+where,paramList.toArray());
	}
	
	//根据条件获得要素集合
	//根据tpCode业务要素，clsCode业务种类判断关联消息类型，如果有多个返回公共列表
	//如果指定了msg，直接获得该msg下的tpCode、clsCode关联的扩展要素
	public List<TC2BisEleBscEbo> getAllBisEle(String msg,String tpCode,String clsCode,String appType) throws AppException{
		if(StringUtil.isNotNullStr(msg)&&StringUtil.isNotNullStr(tpCode)&&StringUtil.isNotNullStr(clsCode)){
			//后续会根据tpCode和clsCode附加扩展要素内容
			return getCfgedBisEle(msg,tpCode,clsCode);
		}
		
		String hql = " select btm from TC2BisTpMsgEbo btm, TC2BisClasEbo bc" ;
		String where = " where btm.tpCode = bc.TC2BisType.tpCode and bc.clsCode = '" + clsCode + "'";
		where += " and btm.tpCode = '" + tpCode + "'";
		where += " and bc.appType = '" + appType + "'";
		where += " and btm.appType = '" + appType + "'";
		List<TC2BisTpMsgEbo> msgs = find(hql+where);
		
		//无对应，返回空
		if(msgs.size()==0) return new ArrayList();
		
		//如果只有一个消息对应，返回
		if(msgs.size()==1) return getCfgedBisEle(msgs.get(0).getMsgCode(),tpCode,clsCode);
		
		Vector bscs = new Vector();
		List<TC2BisEleBscEbo> bscEle = null;
		for (TC2BisTpMsgEbo m : msgs) {
			List<TC2BisEleBscEbo> eles = getCfgedBisEle(m.getMsgCode(),tpCode,clsCode);
			//每次只保留一个
			bscEle = eles;
			Hashtable hash = new Hashtable();
			for(int i=0;i<eles.size();i++){
				TC2BisEleBscEbo e = (TC2BisEleBscEbo)eles.get(i);
				hash.put(e.getEleName(), e);
			}
			bscs.add(hash);
		}
		
		List<TC2BisEleBscEbo> mtchedEles = new ArrayList();
		for(int i=0;i<bscEle.size();i++){
			TC2BisEleBscEbo e = (TC2BisEleBscEbo)bscEle.get(i);
			int matched = 0;
			for(int j=0;j<bscs.size()-1;j++){
				Hashtable h = (Hashtable)bscs.get(j);
				if(h.containsKey(e.getEleName()))
					matched++;
			}
			if(matched == bscs.size()-1)
				mtchedEles.add(e);
			//hash.put(e.getEleName(), e);
		}
		return mtchedEles;
		
	}
}
